package com.second.app.excutor;

import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author GYZ
 * @Date 2024/1/24
 * <pre>
 *   线程池shutDown() 和 shutDownNow()
 *   shutDown(): 使当前未执行完的线程继续执行，而不在添加新的任务task.
 *               该方法不会阻塞，调用后，主线程main马上结束了，而线程池会继续运行直到所有任务执行完才停止
 *               如果不调用shutdown方法，那么线程池会一直保持下去，以便随时执行被添加的任务。
 *   shutDownNow():中断所有的任务task,并且抛出interruptedException异常，
 *                 前提是在runnable中使用if(Thread.currentThread.isInterrupted == true)语句来判断当前线程的中断状态。
 *                 而未执行的线程不在执行，也就是从执行队列中清除。如果没有 if(Thread.currentThread.isInterrupted == true)语句
 *                 和抛出异常的代码，则池中正在运行的线程直到完毕，而未执行的线程不在执行，也从执行队列中清除。
 *
 *   调用shutDown方法，线程池状态立刻变成shutDown状态。此时不能在往线程池中添加任务，
 *   否则将会抛出RejectedExecutionException异常。但是线程池不会立刻推出，知道线程池中的任务都已经处理完成，才会退出。
 *
 *   调用shutDownNow方法，使线程池的状态立刻变为stop状态，并试图停止所有正在执行的线程（如果有if判断则人为
 *   的抛出异常）,不在处理池中的任务。当然他会返回那些未执行的任务。
 *   在调用shutDown方法后，正在执行的任务和队列中的任务后期正常执行。
 * </pre>
 */
class MyRunnable1 implements Runnable {
    @Override
    public void run() {
        try {
            for (int i = 0; i < Integer.MAX_VALUE / 50; i++) {
                String newString = new String();
                Math.random();
                Math.random();
                Math.random();
                Math.random();
                Math.random();
                Math.random();
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("任务没有完成，就中断了");
                    throw new InterruptedException();
                }
            }
            System.out.println("任务成功完成！");
        } catch (InterruptedException e) {
            System.out.println("进入catch中断了任务");
            e.printStackTrace();
        }
    }
}
class Test{
    public static void main(String[] args) {
        MyRunnable1 myRunnable1 = new MyRunnable1();
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2,
                9999,
                9999L,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>());
        pool.execute(myRunnable1);
        pool.execute(myRunnable1);
        pool.execute(myRunnable1);
        pool.execute(myRunnable1);
        //从控制台输出结果来看：剩下的2个任务被取消，没有被运行。
        List<Runnable> runnables = pool.shutdownNow();
        for (int i = 0; i < runnables.size(); i++) {
            MyRunnable1 runnable =(MyRunnable1) runnables.get(i);
            System.out.println(runnable+"任务被取消");
        }
    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {
        try {
            System.out.println("begin " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
            Thread.sleep(4000);
            System.out.println("end " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class DemoRunTarget {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(7, 10,
                0L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
        threadPoolExecutor.execute(myRunnable);
        //关闭线程池
        threadPoolExecutor.shutdown();
        System.out.println("main end!");
    }
}

public class ThreadPoolExecutorShut {

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = () -> {
            try {
                System.out.println("begin " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
                Thread.sleep(4000);
                System.out.println("end " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 9999,
                9999L, TimeUnit.SECONDS, new LinkedBlockingDeque<>());

        for (int i = 0; i < 4; i++) {
            threadPoolExecutor.execute(runnable);
        }
        Thread.sleep(1000);
        threadPoolExecutor.shutdown();

        threadPoolExecutor.execute(runnable);
    }
}
